#include "matrix.h"

void
die(Matrix* m)
{
	for (unsigned i = 0; i < (*m).m; i++)
		free((*m).a[i]);

	free((*m).a);

	free(m);
}

void
print(Matrix m)
{
	for (unsigned i = 0; i < m.m; i++) {
		for (unsigned j = 0; j < m.n; j++)
			printf("%lf\t", m.a[i][j]);
		printf("\n");
	}
}

Matrix
add(Matrix m1, Matrix m2)
{
	if (m1.m != m2.m || m1.n != m2.n)
		exit(-3);

	Matrix m = matrix(m1.m, m1.n);

	for (unsigned i = 0; i < m.m; i++) {
		for (unsigned j = 0; j < m.n; j++)
			m.a[i][j] = m1.a[i][j] + m2.a[i][j];
	}

	return m;
}

Matrix
cpy(Matrix A)
{
	Matrix B = matrix(A.m, A.n);

	for (unsigned int i = 0; i < B.m; i++) {
		for (unsigned int j = 0; j < B.n; j++)
			B.a[i][j] = A.a[i][j];
	}

	return B;
}

Matrix
matrix(unsigned int m, unsigned int n)
{
	Matrix* matrix = malloc(sizeof(Matrix));

	(*matrix).a = malloc(sizeof(double*) * m);

	for (unsigned i = 0; i < m; i++)
		(*matrix).a[i] = malloc(sizeof(double) * n);

	(*matrix).m = m;
	(*matrix).n = n;

	return *matrix;
}

Matrix
mul(Matrix m1, Matrix m2)
{
	if (m1.n != m2.m)
		exit(-3);

	Matrix m = matrix(m1.m, m2.n);

	for (unsigned int i = 0; i < m.m; i++) {
		for (unsigned int j = 0; j < m.n; j++) {
			for (unsigned int k = 0; k < m1.n; k++)
				m.a[i][j] += m1.a[i][k] * m2.a[k][j];
		}
	}

	return m;
}

Matrix
transp(Matrix A)
{
	Matrix B = cpy(A);
	
	for (unsigned int i = 0; i < B.m; i++) {
		for (unsigned int j = 0; j < B.n; j++)
			B.a[i][j] = A.a[j][i];
	}

	return B;
}
